package config

/**
统一配置
*/
import (
	"embed"
	"encoding/json"
	"fmt"
	"gitee.com/snxamdf/wui/logs"
	"io/ioutil"
	"net"
	"strconv"
)

//应用目录配置
var (
	//静态资源目录
	AppResource = "resources"
	env         = ""
	config      = make(map[string]string)
)

func ConfigInit() {
	var (
		byt []byte
		err error
	)
	var conf = fmt.Sprintf("%s/%s", AppResource, "wui-config.json")

	if (embed.FS{}) == _efs {
		byt, err = ioutil.ReadFile(conf)
	} else {
		byt, err = GetEFS().ReadFile(conf)
	}
	if err != nil {
		panic("读取配置文件错误 " + err.Error())
	}
	var configMap = make(map[string]interface{})
	if err := json.Unmarshal(byt, &configMap); err != nil {
		panic("解析配置文件错误" + err.Error())
	}
	if e, ok := configMap["env"]; ok {
		env = e.(string)
	} else {
		panic("解析配置文件错误,环境配置 env 不存在")
	}
	if cfg, ok := configMap[env]; ok {
		for k, v := range cfg.(map[string]interface{}) {
			config[k] = v.(string)
		}
	} else {
		panic("解析配置文件错误,环境配置 " + env + " 不存在")
	}
	logs.Info("config:", config)
	var domain = config["domain"]
	var port = config["port"]
	var addr string
	if port == "*" {
		addr, err = getFreePort()
		if err != nil {
			addr = fmt.Sprintf("%s:80", domain)
			logs.Info("获取随机端口失败,设置默认端口80:", addr)
		}
		logs.Info("监听端口随机获取:", addr)
		var newAddr = fmt.Sprintf("%s", addr)
		config["addr"] = newAddr
	} else {
		config["addr"] = fmt.Sprintf("%s:%s", domain, port)
	}
	logs.Info("当前环境为", env)
}

func GetConfig(key string) string {
	if r, ok := config[key]; ok {
		return r
	} else {
		return ""
	}
}

func GetConfigInt(key string) int {
	r, err := strconv.Atoi(GetConfig(key))
	if err != nil {
		logs.Error("获得配置参数失败 to int:", err)
		return 0
	}
	return r
}

func GetEnv() string {
	return env
}

func IsEnvDev() bool {
	if env == "dev" {
		return true
	}
	return false
}

func IsEnvProd() bool {
	if env == "prod" {
		return true
	}
	return false
}

func getFreePort() (string, error) {
	addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
	if err != nil {
		return "", err
	}
	l, err := net.ListenTCP("tcp", addr)
	if err != nil {
		return "", err
	}
	defer l.Close()
	return l.Addr().String(), nil
}
